extends CharacterBody2D
class_name Unit

#region 节点引用
@onready var bt_player: BTPlayer = $BTPlayer
@onready var _global_cooldown: Timer = $GlobalCooldown
@onready var animation_player: AnimationPlayer = $AnimationPlayer
#endregion

#region 导出属性
@export var speed := 50
@export var target_group := "enemy"
@export var group := "ally"
@export var unit_name := "Unamed"
@export var icon_path := ""
@export var scene_path := ""
#endregion

#region 技能系统
@export var base_skills: Array[String] = [] # 基础技能列表
var all_skills: Array[String] = [] # 全部技能标识
var all_skill_instances: Array[Skill] = [] # 实例化技能对象
var can_execute_skills: Array[Skill] = [] # 当前可释放技能
#endregion

#region 战斗属性
var current_target: Unit # 当前目标单位
var min_attack_range := 9999.0 # 最小攻击范围
var is_attacking := false # 攻击状态标记
var _base_global_cooldown := 1.0 # 基础全局冷却时间
var is_death := false
#endregion
@onready var nav_agent: NavigationAgent2D = $Pathfinder
@onready var target_enter_area: Area2D = $TargetEnterArea
@onready var area_collision: CollisionShape2D = $TargetEnterArea/AreaCollision
var area_enemies: Array[Unit] = []
var direct_line: Line2D

#region 生命周期方法
func _ready():
	"""初始化，连接信号并刷新技能"""
	_connect_signals()
	_emit_signals()
	_instantiate_skills()

#endregion

#region 信号处理
func _connect_signals():
	"""连接全局信号和计时器信号"""
	GlobalSignal.gs_unit_created.emit(self)
	GlobalSignal.gs_before_skill_used.connect(_on_before_skill_used)
	_global_cooldown.timeout.connect(_on_global_cooldown_finished)
	target_enter_area.body_entered.connect(_on_target_area_body_entered)
	nav_agent.velocity_computed.connect(_on_velocity_computed)
 
func _emit_signals():
	"""发射信号"""
	GlobalSignal.gs_unit_created.emit(self)
#func _physics_process(delta):
#	# 更新方向线
#	if is_instance_valid(current_target):
#		direct_line.points = [Vector2.ZERO, current_target.global_position - global_position]
	#if velocity.length() > 0:
	#	var direction = velocity.normalized()
	#	direct_line.points = [Vector2.ZERO, direction * 20]
	#else:
	#	direct_line.points = []

func _on_before_skill_used(caster: Unit, _target: Unit, skill: Skill):
	"""技能使用前处理全局冷却"""
	if caster != self:
		return

	# 计算实际冷却时间（取全局冷却和技能前摇的最大值）
	var actual_cooldown = max(get_global_cooldown_time(), skill.cast_time)

	# 启动全局冷却计时器
	_global_cooldown.wait_time = actual_cooldown
	_global_cooldown.start()

	# 更新攻击状态
	is_attacking = true


func _on_global_cooldown_finished():
	"""全局冷却结束回调"""
	is_attacking = false
	GlobalSignal.emit_signal("gs_global_cooldown_ended", self)
#endregion

#region 技能系统方法
func use_skill():
	"""使用随机可选技能"""
	if can_execute_skills.is_empty():
		return

	var skill: Skill = can_execute_skills.pick_random()
	skill.set_target(current_target)
	skill.execute()


func in_attack_range() -> bool:
	"""检查目标是否在可攻击范围内，并更新可用技能列表"""
	_update_min_attack_range()
	can_execute_skills.clear()
	# 目标有效性检查
	if not is_instance_valid(current_target):
		return false

	# 计算实际距离和最小需求距离
	var actual_distance = global_position.distance_to(current_target.global_position)
	var min_required_range = actual_distance - 10 # 10像素冗余

	# 筛选可用技能
	for skill in all_skill_instances:
		if _is_skill_available(skill, min_required_range):
			can_execute_skills.append(skill)
	if min_required_range <= min_attack_range:
		return true
	

	return not can_execute_skills.is_empty()


func _is_skill_available(skill: Skill, required_range: float) -> bool:
	"""检查技能是否可用"""
	return (
	not skill.is_on_cooldown
	and not is_attacking
	and max(skill.skill_range, min_attack_range) >= required_range
	)


func _update_min_attack_range():
	"""更新最小攻击范围（根据所有技能）"""
	min_attack_range = 9999
	for skill in all_skill_instances:
		if skill.skill_range < min_attack_range:
			min_attack_range = skill.skill_range
			_update_attack_area()
#endregion


func _instantiate_skills():
	"""实例化所有技能对象"""
	all_skill_instances.clear()

	for skill_name in all_skills + base_skills:
		var path = "res://game/02_scripts/effect/skill_resource/%s.gd" % skill_name
		if ResourceLoader.exists(path):
			var skill_class = load(path)
			if skill_class and skill_class is GDScript:
				var skill = skill_class.new()
				if skill is Skill:
					skill.set_caster(self)
					all_skill_instances.append(skill)
				else:
					push_error("无效技能类: %s" % skill_name)
		else:
			push_warning("技能文件不存在: %s" % path)
#endregion

#region 全局冷却系统
func get_global_cooldown_time() -> float:
	"""动态计算全局冷却时间"""
	var final_gcd = _base_global_cooldown

	# 确保最小冷却时间
	return max(0.1, final_gcd)
#endregion

#region 通用功能
func deal_damage(_skill: Skill):
	pass


func take_damage(_skill: Skill, _damage: Damage):
	pass
	
	
func is_target_valid():
	if not is_instance_valid(current_target):
		return false
	if current_target.is_death:
		return false
	return true
#endregion

func _on_target_area_body_entered(body: Unit):
	if not is_instance_valid(body) or not body is Unit:
		return
	
	var new_target = body as Unit
	
	# 初始化情况：没有当前目标时直接设置
	if not is_instance_valid(current_target):
		current_target = new_target
		return
	
	# 比较距离
	var current_distance = global_position.distance_to(current_target.global_position)
	var new_distance = global_position.distance_to(new_target.global_position)
	
	# 选择更近的目标
	if new_distance < current_distance - 5:
		current_target = new_target
		

func _update_attack_area():
	# 更新碰撞体形状为圆形
	var rect = area_collision.shape
	rect.size = Vector2(
		min_attack_range + 100,
		min_attack_range + 20
	)


func _on_velocity_computed(safe_velocity):
	velocity = safe_velocity
